#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <dirent.h>
#include <sys/stat.h>
#include <stdbool.h>
#include <unistd.h>

void match_file(char *pattern,char *filename, bool recursive)
{
    FILE *file = fopen(filename, "r");
    if (file == NULL) {
        fprintf(stderr, "Error opening file %s\n", filename);
        return;
    }
    char line[1024];
    while (fgets(line, sizeof(line), file)) {
        if (strstr(line, pattern) != NULL) {
            if(recursive){
                printf("%s: ", filename);
            }
            printf("%s", line);
        }
    }
    fclose(file);
}

void search_dir(char *pattern, char *path, bool recursive)
{
    struct stat attr;
    if (stat(path, &attr) != 0) {
        fprintf(stderr, "Error accessing path %s\n", path);
        return;
    }
    if(S_ISREG(attr.st_mode)) {
        match_file(pattern, path, recursive);
        return;
    }
    if(!S_ISDIR(attr.st_mode)) {
        fprintf(stderr, "%s is not a directory\n", path);
        return;
    }
    DIR *dir;
    struct dirent *entry;
    dir = opendir(path);
    while((entry=readdir(dir))!= NULL) {
        if(entry->d_name[0] == '.') {
            continue; // Skip hidden files and directories
        }
        char fullpath[1024];
        snprintf(fullpath, sizeof(fullpath), "%s/%s", path, entry->d_name);
        search_dir(pattern, fullpath, recursive);
    }

}

int main(int argc, char *argv[]) {
    int opt;
    bool recursive=false;
    while((opt=getopt(argc, argv, "r")) != -1)
    {
        switch(opt) {
            case 'r':
            {
                recursive = true;
                break;
            }
            default:
            {
                fprintf(stderr, "Usage: %s [-r] <pattern> [path]\n", argv[0]);
                exit(EXIT_FAILURE);
            }
        }
    }
    if (optind == argc) {
        fprintf(stderr, "Usage: %s [-r] <pattern> [path]\n", argv[0]);
        exit(EXIT_FAILURE);
    }
    char *pattern = argv[optind];
    if(optind + 1 == argc)
    {
        if(recursive)
        {
            search_dir(pattern, ".", recursive);
        }
        else
        {
            perror("No path specified, use -r for recursive search or specify a path");
            exit(EXIT_FAILURE);
        }
        return 0;
    }
    for (int i = optind + 1; i < argc; i++)
    {
        char *path = argv[i];
        if(recursive)
        {
            search_dir(pattern, path, recursive);
        }
        else
        {
            match_file(pattern, path, recursive);
        }
    }
}
